package com.microframework.base.data.utils;

import okhttp3.*;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.jfinal.kit.JsonKit;
import com.microframework.boot.collect.model.domain.DataSourceConfig;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

import javax.crypto.Mac;

public class HttpClientWithAuth {

    private static final DateTimeFormatter AWS_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'")
            .withZone(ZoneId.of("UTC"));
    private static final DateTimeFormatter AWS_DATE_ONLY_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd")
            .withZone(ZoneId.of("UTC"));

    public JSONObject post(DataSourceConfig dataSourceConfig, JSONObject connection, JSONObject authorization,
                    List<JSONObject> headers, List<JSONObject> queryParams, JSONObject body, JSONObject result) {
        
    	JSONObject jsonObject=new JSONObject();
    	
        String url = connection.getString("url");
        String method = connection.getString("method");
        int timeout = connection.getIntValue("timeout");
        String authType = authorization.getString("authType").toLowerCase();

        // 创建OkHttpClient
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
                .connectTimeout(timeout, TimeUnit.MILLISECONDS)
                .readTimeout(timeout, TimeUnit.MILLISECONDS)
                .writeTimeout(timeout, TimeUnit.MILLISECONDS);

        // 构建基础请求
        HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
        Request.Builder requestBuilder = new Request.Builder();

        // 添加查询参数
        addQueryParams(urlBuilder, queryParams);
        
        // 处理各种认证方式
        switch (authType) {
            case "basic":
                handleBasicAuth(authorization, requestBuilder, urlBuilder);
                break;
            case "bearer":
                handleBearerToken(authorization, requestBuilder, urlBuilder);
                break;
            case "api_key":
                handleApiKey(authorization, requestBuilder, urlBuilder);
                break;
            case "oauth2":
                handleOAuth2(authorization, requestBuilder, urlBuilder);
                break;
            case "jwt":
                handleJWT(authorization, requestBuilder, urlBuilder);
                break;
            case "hmac":
                handleHMAC(authorization, requestBuilder, urlBuilder, method, url, body);
                break;
            case "aws":
                handleAWSSignature(authorization, requestBuilder, urlBuilder, method, url, headers, body);
                break;
            case "digest":
                handleDigestAuth(authorization, clientBuilder, requestBuilder);
                break;
            case "ntlm":
                handleNTLMAuth(authorization, clientBuilder);
                break;
        }

        // 添加请求头
        addHeaders(requestBuilder, headers);
        
        
        // 获取 body 类型
        String bodyType = body.getString("type"); // none | form-data | x-www-form-urlencoded | raw

        RequestBody requestBody = null;

        if (body != null && !body.isEmpty()) {
            if ("form-data".equalsIgnoreCase(bodyType)) {
                // multipart/form-data 格式
    			List<JSONObject> formDataFields = JSON.parseObject(body.getString("content"), new TypeReference<List<JSONObject>>() {});
    			JSONObject formData=ParamFieldParseUtil.buildJsonFromFields(formDataFields);
    			MultipartBody multipartBody=MultipartFormDataBuilder.buildMultipartFormData(formData);
                requestBody = multipartBody;
            } else if ("x-www-form-urlencoded".equalsIgnoreCase(bodyType)) {
                // application/x-www-form-urlencoded 格式
    			List<JSONObject> formDataFields = JSON.parseObject(body.getString("content"), new TypeReference<List<JSONObject>>() {});
    			JSONObject formParams=ParamFieldParseUtil.buildJsonFromFields(formDataFields);
                requestBody = UrlEncodedFormBuilder.buildUrlEncodedForm(formParams);
                
            } else if ("raw".equalsIgnoreCase(bodyType)) {
                // raw 原始数据格式
                String rawType = body.getString("rawType"); // Text | JavaScript | JSON | HTML | XML
                switch (rawType.toLowerCase()) {
                    case "text":
                        getRequestBody(body,MediaType.parse("text/plain; charset=utf-8"));
                        break;
                    case "javascript":
                        getRequestBody(body,MediaType.parse("application/javascript; charset=utf-8"));
                        break;
                    case "json":
            			List<JSONObject> formDataFields = JSON.parseObject(body.getString("content"), new TypeReference<List<JSONObject>>() {});
            			JSONObject json=ParamFieldParseUtil.buildJsonFromFields(formDataFields);
            			
            			System.out.println(JsonKit.toJson(json));
            			System.out.println(json.toJSONString());
            			requestBody = RequestBody.create(
            				    json.toJSONString(),
            				    MediaType.parse("application/json; charset=utf-8")
            				);
                        break;
                    case "html":
                        getRequestBody(body,MediaType.parse("text/html; charset=utf-8"));
                        break;
                    case "xml":
                        getRequestBody(body,MediaType.parse("application/xml; charset=utf-8"));
                        break;
                    default:
                        getRequestBody(body,MediaType.parse("text/plain; charset=utf-8"));
                }
            } else {
                requestBody = RequestBody.create(
                    body.toJSONString(), 
                    MediaType.parse("application/json; charset=utf-8"));
            }
        }

        requestBuilder.url(urlBuilder.build())
                .method(method, requestBody);

        // 执行请求
        try (Response response = clientBuilder.build().newCall(requestBuilder.build()).execute()) {
            if (response.isSuccessful()) {
                String responseBody = response.body() != null ? response.body().string() : "";
                jsonObject.put("status", "success");
                jsonObject.put("data", JSONObject.parseObject(responseBody));
                jsonObject.put("headers", convertHeaders(response.headers()));
                jsonObject.put("message", response.message());
            } else {
            	jsonObject.put("status", "error");
            	jsonObject.put("error", "HTTP error: " + response.code());
            	jsonObject.put("message", response.message());
            }
        } catch (Exception e) {
        	jsonObject.put("status", "error");
        	jsonObject.put("error", "Request failed: " + e.getMessage());
        }
        return jsonObject;
    }
    
    private RequestBody getRequestBody(JSONObject body,MediaType mediaType) {
        return RequestBody.create(body.getString("content"), mediaType);
    }

    // ========== 认证方式实现 ==========

    /**
     * Basic认证处理
     */
    private void handleBasicAuth(JSONObject authorization, Request.Builder requestBuilder, HttpUrl.Builder urlBuilder) {
        String location = authorization.getString("basicAuthLocation");
        String username = authorization.getString("basicAuthUsername");
        String password = authorization.getString("basicAuthPassword");

        if (username == null || password == null) return;

        String credentials = Credentials.basic(username, password);

        if ("header".equalsIgnoreCase(location)) {
            String headerKey = authorization.getString("basicAuthHeaderKey");
            if (headerKey == null) headerKey = "Authorization";
            requestBuilder.addHeader(headerKey, credentials);
        } else if ("query".equalsIgnoreCase(location)) {
            String queryKey = authorization.getString("basicAuthQueryKey");
            if (queryKey == null) queryKey = "auth";
            urlBuilder.addQueryParameter(queryKey, Base64.getEncoder()
                    .encodeToString((username + ":" + password).getBytes()));
        }
    }

    /**
     * Bearer Token处理
     */
    private void handleBearerToken(JSONObject authorization, Request.Builder requestBuilder, HttpUrl.Builder urlBuilder) {
        String location = authorization.getString("bearerTokenLocation");
        String token = getBearerToken(authorization);

        if (token == null) return;

        if ("header".equalsIgnoreCase(location)) {
            String headerKey = authorization.getString("bearerTokenHeaderKey");
            if (headerKey == null) headerKey = "Authorization";
            requestBuilder.addHeader(headerKey, "Bearer " + token);
        } else if ("query".equalsIgnoreCase(location)) {
            String queryKey = authorization.getString("bearerTokenQueryKey");
            if (queryKey == null) queryKey = "access_token";
            urlBuilder.addQueryParameter(queryKey, token);
        } else if ("cookie".equalsIgnoreCase(location)) {
            String cookieKey = authorization.getString("bearerTokenCookieKey");
            if (cookieKey == null) cookieKey = "token";
            requestBuilder.addHeader("Cookie", cookieKey + "=" + token);
        }
    }

    private String getBearerToken(JSONObject authorization) {
        String fromRedis = authorization.getString("authBearerFromRedisRead");
        if ("1".equals(fromRedis)) {
            // 模拟从Redis获取token
            String redisKey = authorization.getString("authBearerRedisReadKey");
            // 实际项目中这里应该从Redis获取
            return "redis_token_" + redisKey;
        } else {
            return authorization.getString("authBearerToken");
        }
    }

    /**
     * API Key处理
     */
    private void handleApiKey(JSONObject authorization, Request.Builder requestBuilder, HttpUrl.Builder urlBuilder) {
        String location = authorization.getString("apiKeyLocation");
        String key = authorization.getString("apiKeyValue");

        if (key == null) return;

        if ("header".equalsIgnoreCase(location)) {
            String headerKey = authorization.getString("apiKeyHeaderKey");
            if (headerKey == null) headerKey = "X-API-KEY";
            requestBuilder.addHeader(headerKey, key);
        } else if ("query".equalsIgnoreCase(location)) {
            String queryKey = authorization.getString("apiKeyQueryKey");
            if (queryKey == null) queryKey = "api_key";
            urlBuilder.addQueryParameter(queryKey, key);
        }
    }

    /**
     * OAuth2处理
     */
    private void handleOAuth2(JSONObject authorization, Request.Builder requestBuilder, HttpUrl.Builder urlBuilder) {
        String location = authorization.getString("oauth2TokenLocation");
        String token = null;
		try {
			token = getOAuth2Token(authorization);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

        if (token == null) return;

        if ("header".equalsIgnoreCase(location)) {
            String headerKey = authorization.getString("oauth2HeaderKey");
            if (headerKey == null) headerKey = "Authorization";
            requestBuilder.addHeader(headerKey, "Bearer " + token);
        } else if ("query".equalsIgnoreCase(location)) {
            String queryKey = authorization.getString("oauth2QueryKey");
            if (queryKey == null) queryKey = "access_token";
            urlBuilder.addQueryParameter(queryKey, token);
        } else if ("cookie".equalsIgnoreCase(location)) {
            String cookieKey = authorization.getString("oauth2CookieKey");
            if (cookieKey == null) cookieKey = "oauth_token";
            requestBuilder.addHeader("Cookie", cookieKey + "=" + token);
        }
    }

    private String getOAuth2Token(JSONObject authorization) throws IOException {
        // 如果已有直接可用的token，直接返回
        String existingToken = authorization.getString("oauth2Token");
        if (existingToken != null && !existingToken.isEmpty()) {
            return existingToken;
        }

        // 获取授权类型
        String grantType = authorization.getString("oauth2GrantType");
        if (!"client_credentials".equalsIgnoreCase(grantType)) {
            throw new IllegalArgumentException("Unsupported OAuth2 grant type: " + grantType);
        }

        // 获取必要参数
        String tokenUrl = authorization.getString("oauth2TokenUrl");
        String clientId = authorization.getString("oauth2ClientId");
        String clientSecret = authorization.getString("oauth2ClientSecret");
        String scope = authorization.getString("oauth2Scope");

        if (tokenUrl == null || clientId == null || clientSecret == null) {
            throw new IllegalArgumentException("Missing required OAuth2 parameters");
        }

        // 构建请求体
        FormBody.Builder formBuilder = new FormBody.Builder()
                .add("grant_type", "client_credentials")
                .add("client_id", clientId)
                .add("client_secret", clientSecret);

        if (scope != null && !scope.isEmpty()) {
            formBuilder.add("scope", scope);
        }

        // 创建HTTP请求
        Request request = new Request.Builder()
                .url(tokenUrl)
                .post(formBuilder.build())
                .addHeader("Accept", "application/json")
                .build();

        // 执行请求
        OkHttpClient client = new OkHttpClient();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("OAuth2 token request failed: " + response.code() + " " + response.message());
            }

            // 解析响应
            ResponseBody responseBody = response.body();
            if (responseBody == null) {
                throw new IOException("Empty response from OAuth2 server");
            }

            JSONObject tokenResponse = JSONObject.parseObject(responseBody.string());
            String accessToken = tokenResponse.getString("access_token");
            if (accessToken == null) {
                throw new IOException("Invalid OAuth2 token response: missing access_token");
            }

            // 可选：处理过期时间和刷新令牌
            Integer expiresIn = tokenResponse.getInteger("expires_in");
            String refreshToken = tokenResponse.getString("refresh_token");

            return accessToken;
        }
    }

    /**
     * JWT处理
     */
    private void handleJWT(JSONObject authorization, Request.Builder requestBuilder, HttpUrl.Builder urlBuilder) {
        String location = authorization.getString("jwtLocation");
        String token = authorization.getString("jwtToken");

        if (token == null) return;

        if ("header".equalsIgnoreCase(location)) {
            String headerKey = authorization.getString("jwtHeaderKey");
            if (headerKey == null) headerKey = "Authorization";
            requestBuilder.addHeader(headerKey, "Bearer " + token);
        } else if ("query".equalsIgnoreCase(location)) {
            String queryKey = authorization.getString("jwtQueryKey");
            if (queryKey == null) queryKey = "token";
            urlBuilder.addQueryParameter(queryKey, token);
        } else if ("cookie".equalsIgnoreCase(location)) {
            String cookieKey = authorization.getString("jwtCookieKey");
            if (cookieKey == null) cookieKey = "jwt_token";
            requestBuilder.addHeader("Cookie", cookieKey + "=" + token);
        }
    }

    /**
     * HMAC处理
     */
    private void handleHMAC(JSONObject authorization, Request.Builder requestBuilder, 
                          HttpUrl.Builder urlBuilder, String method, String url, JSONObject body) {
        String location = authorization.getString("hmacKeyLocation");
        String secret = authorization.getString("hmacSecret");
        String algorithm = authorization.getString("hmacAlgorithm");

        if (secret == null) return;
        if (algorithm == null) algorithm = "HmacSHA256";

        // 生成签名内容
        String contentToSign = buildContentToSign(method, url, body);
        String signature = generateHMACSignature(contentToSign, secret, algorithm);

        if ("header".equalsIgnoreCase(location)) {
            String headerKey = authorization.getString("hmacHeaderKey");
            if (headerKey == null) headerKey = "X-HMAC-Signature";
            requestBuilder.addHeader(headerKey, signature);
            
            String signatureHeader = authorization.getString("hmacSignatureHeader");
            if (signatureHeader != null) {
                requestBuilder.addHeader(signatureHeader, signature);
            }
        } else if ("query".equalsIgnoreCase(location)) {
            String queryKey = authorization.getString("hmacQueryKey");
            if (queryKey == null) queryKey = "signature";
            urlBuilder.addQueryParameter(queryKey, signature);
        }
    }

    private String buildContentToSign(String method, String url, JSONObject body) {
        // 简化的签名内容构建，实际应根据API要求实现
        StringBuilder sb = new StringBuilder();
        sb.append(method).append("\n")
          .append(url).append("\n");
        
        if (body != null) {
            sb.append(body.toJSONString());
        }
        
        return sb.toString();
    }

    private String generateHMACSignature(String data, String secret, String algorithm) {
        try {
            HmacAlgorithms hmacAlgorithm = HmacAlgorithms.HMAC_SHA_256;
            if ("HmacSHA1".equalsIgnoreCase(algorithm)) {
                hmacAlgorithm = HmacAlgorithms.HMAC_SHA_1;
            } else if ("HmacSHA512".equalsIgnoreCase(algorithm)) {
                hmacAlgorithm = HmacAlgorithms.HMAC_SHA_512;
            }
            
            return new HmacUtils(hmacAlgorithm, secret.getBytes())
                    .hmacHex(data.getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            throw new RuntimeException("Failed to generate HMAC signature", e);
        }
    }

    /**
     * AWS签名处理 (AWS Signature Version 4)
     */
    private void handleAWSSignature(JSONObject authorization, Request.Builder requestBuilder, 
                                  HttpUrl.Builder urlBuilder, String method, String url, 
                                  List<JSONObject> headers, JSONObject body) {
        String location = authorization.getString("awsSignatureLocation");
        String accessKey = authorization.getString("awsAccessKey");
        String secretKey = authorization.getString("awsSecretKey");
        String region = authorization.getString("awsRegion");
        String service = authorization.getString("awsService");

        if (accessKey == null || secretKey == null || region == null || service == null) {
            return;
        }

        // 1. 创建规范请求
        String amzDate = AWS_DATE_FORMATTER.format(Instant.now());
        String dateStamp = AWS_DATE_ONLY_FORMATTER.format(Instant.now());

        // 2. 创建签名密钥
        byte[] signingKey = getSignatureKey(secretKey, dateStamp, region, service);

        // 3. 创建待签字符串
        String canonicalRequest = createCanonicalRequest(method, url, headers, body, amzDate);
        String stringToSign = createStringToSign(amzDate, dateStamp, region, service, canonicalRequest);

        // 4. 计算签名
        String signature = calculateSignature(signingKey, stringToSign);

        // 5. 添加签名到请求
        String credentialScope = dateStamp + "/" + region + "/" + service + "/aws4_request";
        String authorizationHeader = "AWS4-HMAC-SHA256 " +
                "Credential=" + accessKey + "/" + credentialScope + ", " +
                "SignedHeaders=" + getSignedHeaders(headers) + ", " +
                "Signature=" + signature;

        if ("header".equalsIgnoreCase(location)) {
            String headerKey = authorization.getString("awsSignatureKey");
            if (headerKey == null) headerKey = "Authorization";
            requestBuilder.addHeader(headerKey, authorizationHeader);
            requestBuilder.addHeader("x-amz-date", amzDate);
        } else if ("query".equalsIgnoreCase(location)) {
            // 查询参数形式的AWS签名比较复杂，这里简化处理
            urlBuilder.addQueryParameter("X-Amz-Algorithm", "AWS4-HMAC-SHA256")
                    .addQueryParameter("X-Amz-Credential", accessKey + "/" + credentialScope)
                    .addQueryParameter("X-Amz-Date", amzDate)
                    .addQueryParameter("X-Amz-SignedHeaders", getSignedHeaders(headers))
                    .addQueryParameter("X-Amz-Signature", signature);
        }
    }

    private byte[] getSignatureKey(String key, String dateStamp, String regionName, String serviceName) {
        byte[] kSecret = ("AWS4" + key).getBytes(StandardCharsets.UTF_8);
        byte[] kDate = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, kSecret)
                .hmac(dateStamp.getBytes(StandardCharsets.UTF_8));
        byte[] kRegion = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, kDate)
                .hmac(regionName.getBytes(StandardCharsets.UTF_8));
        byte[] kService = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, kRegion)
                .hmac(serviceName.getBytes(StandardCharsets.UTF_8));
        return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, kService)
                .hmac("aws4_request".getBytes(StandardCharsets.UTF_8));
    }

    private String createCanonicalRequest(String method, String url, List<JSONObject> headers, 
                                         JSONObject body, String amzDate) {
        // 实现规范请求的创建
        // 简化为基本实现，实际应根据AWS规范完整实现
        return method + "\n" +
                getCanonicalURI(url) + "\n" +
                getCanonicalQueryString(url) + "\n" +
                getCanonicalHeaders(headers) + "\n" +
                getSignedHeaders(headers) + "\n" +
                getPayloadHash(body);
    }

    private String createStringToSign(String amzDate, String dateStamp, String region, 
                                    String service, String canonicalRequest) {
        return "AWS4-HMAC-SHA256\n" +
                amzDate + "\n" +
                dateStamp + "/" + region + "/" + service + "/aws4_request\n" +
                hash(canonicalRequest);
    }

    private String calculateSignature(byte[] signingKey, String stringToSign) {
        Mac mac = HmacUtils.getInitializedMac(HmacAlgorithms.HMAC_SHA_256, signingKey);
        byte[] signature = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        return bytesToHex(signature);
    }

    // ========== 辅助方法 ==========

    private void addQueryParams(HttpUrl.Builder urlBuilder, List<JSONObject> queryParams) {
    	if (queryParams != null && !queryParams.isEmpty()) {
    		JSONObject combinedJson = ParamFieldParseUtil.buildJsonFromFields(queryParams);
            if (combinedJson != null) {
                for (Map.Entry<String, Object> entry : combinedJson.entrySet()) {
                    if (entry.getKey() != null && entry.getValue() != null) {
                        urlBuilder.addQueryParameter(entry.getKey(), entry.getValue().toString());
                    }
                }
            }
    	}
    }

    private void addHeaders(Request.Builder requestBuilder, List<JSONObject> headers) {
        if (headers != null && !headers.isEmpty()) {
            JSONObject combinedJson = ParamFieldParseUtil.buildJsonFromFields(headers);
            if (combinedJson != null) {
                for (Map.Entry<String, Object> entry : combinedJson.entrySet()) {
                    if (entry.getKey() != null && entry.getValue() != null) {
                    	requestBuilder.addHeader(entry.getKey(), entry.getValue().toString());
                    }
                }
            }
        }
    }

    private JSONObject convertHeaders(Headers headers) {
        JSONObject result = new JSONObject();
        for (String name : headers.names()) {
            result.put(name, headers.get(name));
        }
        return result;
    }

    private String getCanonicalURI(String url) {
        // 简化实现，实际应解析URL路径
        try {
            HttpUrl httpUrl = HttpUrl.parse(url);
            return httpUrl != null ? httpUrl.encodedPath() : "/";
        } catch (Exception e) {
            return "/";
        }
    }

    private String getCanonicalQueryString(String url) {
        // 简化实现，实际应解析URL查询参数并排序
        try {
            HttpUrl httpUrl = HttpUrl.parse(url);
            if (httpUrl == null) return "";

            List<String> queryNames = new ArrayList<>();
            for (String name : httpUrl.queryParameterNames()) {
                queryNames.add(name);
            }
            Collections.sort(queryNames);

            StringBuilder result = new StringBuilder();
            for (String name : queryNames) {
                if (result.length() > 0) result.append("&");
                result.append(name).append("=").append(httpUrl.queryParameter(name));
            }
            return result.toString();
        } catch (Exception e) {
            return "";
        }
    }

    private String getCanonicalHeaders(List<JSONObject> headers) {
        // 简化实现
        StringBuilder result = new StringBuilder();
        for (JSONObject header : headers) {
            String key = header.getString("key");
            String value = header.getString("value");
            if (key != null && value != null) {
                result.append(key.toLowerCase()).append(":").append(value.trim()).append("\n");
            }
        }
        return result.toString();
    }

    private String getSignedHeaders(List<JSONObject> headers) {
        // 简化实现
        List<String> headerNames = new ArrayList<>();
        for (JSONObject header : headers) {
            String key = header.getString("key");
            if (key != null) {
                headerNames.add(key.toLowerCase());
            }
        }
        Collections.sort(headerNames);
        return String.join(";", headerNames);
    }

    private String getPayloadHash(JSONObject body) {
        if (body == null || body.isEmpty()) {
            return hash("");
        }
        return hash(body.toJSONString());
    }

    private String hash(String text) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(text.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Failed to calculate hash", e);
        }
    }

    private String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    /**
     * Digest认证处理
     */
    private void handleDigestAuth(JSONObject authorization, OkHttpClient.Builder clientBuilder, 
                                Request.Builder requestBuilder) {
        String username = authorization.getString("digestUsername");
        String password = authorization.getString("digestPassword");

        if (username == null || password == null) return;

        clientBuilder.authenticator(new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) throws IOException {
                String challenge = response.header("WWW-Authenticate");
                if (challenge == null || !challenge.startsWith("Digest")) {
                    return null;
                }

                Map<String, String> authParams = parseDigestChallenge(challenge);
                String realm = authParams.get("realm");
                String nonce = authParams.get("nonce");
                String qop = authParams.get("qop");
                String algorithm = authParams.get("algorithm");
                String opaque = authParams.get("opaque");

                String cnonce = Long.toHexString(System.currentTimeMillis());
                String nc = "00000001";

                String ha1 = md5(username + ":" + realm + ":" + password);
                if ("MD5-sess".equalsIgnoreCase(algorithm)) {
                    ha1 = md5(ha1 + ":" + nonce + ":" + cnonce);
                }

                String ha2 = md5(response.request().method() + ":" + response.request().url().uri().getPath());
                String responseHash;
                if (qop == null) {
                    responseHash = md5(ha1 + ":" + nonce + ":" + ha2);
                } else {
                    responseHash = md5(ha1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + ha2);
                }

                String authHeader = String.format(
                        "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
                        username, realm, nonce, response.request().url().uri().getPath(), responseHash);

                if (qop != null) {
                    authHeader += String.format(", qop=%s, nc=%s, cnonce=\"%s\"", qop, nc, cnonce);
                }
                if (algorithm != null) {
                    authHeader += String.format(", algorithm=%s", algorithm);
                }
                if (opaque != null) {
                    authHeader += String.format(", opaque=\"%s\"", opaque);
                }

                return response.request().newBuilder()
                        .header("Authorization", authHeader)
                        .build();
            }
        });
    }

    private Map<String, String> parseDigestChallenge(String challenge) {
        Map<String, String> params = new HashMap<>();
        String[] parts = challenge.substring(7).split(",");
        for (String part : parts) {
            String[] keyValue = part.trim().split("=", 2);
            if (keyValue.length == 2) {
                params.put(keyValue[0], keyValue[1].replace("\"", ""));
            }
        }
        return params;
    }

    private String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(digest);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 not supported", e);
        }
    }

    /**
     * NTLM认证处理
     */
    private void handleNTLMAuth(JSONObject authorization, OkHttpClient.Builder clientBuilder) {
        String username = authorization.getString("ntlmUsername");
        String password = authorization.getString("ntlmPassword");
        String domain = authorization.getString("ntlmDomain");

        if (username == null || password == null) return;

        clientBuilder.authenticator(new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) throws IOException {
                String challengeHeader = response.header("WWW-Authenticate");
                if (challengeHeader == null || !challengeHeader.startsWith("NTLM")) {
                    return null;
                }

                // 简化的NTLM认证流程，实际应使用完整实现
                String type1Msg = NTLMEngineImpl.getType1Message(domain, "WORKSTATION");
                Request.Builder builder = response.request().newBuilder()
                        .header("Authorization", "NTLM " + type1Msg);

                Response type1Response = clientBuilder.build().newCall(builder.build()).execute();
                String type2Msg = type1Response.header("WWW-Authenticate");
                if (type2Msg == null || !type2Msg.startsWith("NTLM")) {
                    return null;
                }

                String type3Msg = NTLMEngineImpl.getType3Message(username, password, domain, 
                        "WORKSTATION", type2Msg.substring(5));
                return response.request().newBuilder()
                        .header("Authorization", "NTLM " + type3Msg)
                        .build();
            }
        });
    }

    // 简化的NTLM引擎实现
    private static class NTLMEngineImpl {
        static String getType1Message(String domain, String workstation) {
            return Base64.getEncoder().encodeToString(("NTLMSSP\0" + domain + workstation).getBytes());
        }

        static String getType3Message(String user, String password, String domain, 
                                    String workstation, String challenge) {
            return Base64.getEncoder().encodeToString(("NTLMSSP\0" + user + password + domain + 
                    workstation + new String(Base64.getDecoder().decode(challenge))).getBytes());
        }
    }
}